import { type RouteRecordRaw, createRouter } from 'vue-router';
import { history, flatMultiLevelRoutes } from './helper';
import routeSettings from '@/config/route';

const Layouts = () => import('@/layouts/index.vue');

/**
 * 常驻路由
 * 除了 redirect/403/404/login 等隐藏页面，其他页面建议设置 Name 属性
 */
export const constantRoutes: RouteRecordRaw[] = [
	// #region
	/*
    {
      //? 设置 noRedirect 的时候该路由在面包屑导航中不可被点击
      redirect: 'noRedirect'
      //? 动态路由：必须设定路由的名字，一定要填写不然重置路由可能会出问题
      //? 如果要在 tags-view 中展示，也必须填 name
      name: 'router-name'
      meta: {
        //? 设置该路由在侧边栏和面包屑中展示的名字
        title: 'title'
        //? 设置该路由的图标，记得将 svg 导入 @/icons/svg
        svgIcon: 'svg name'
        //? 设置该路由的图标，直接使用 Element Plus 的 Icon（与 svgIcon 同时设置时，svgIcon 将优先生效）
        elIcon: 'element-plus icon name'
        //? 默认 false，设置 true 的时候该路由不会在侧边栏出现
        hidden: true
        //? 设置该路由进入的权限，支持多个权限叠加（动态路由才需要设置）
        roles: ['admin', 'editor']
        //? 默认 true，如果设置为 false，则不会在面包屑中显示
        breadcrumb: false
        //? 默认 false，如果设置为 true，它则会固定在 tags-view 中
        affix: true
        //? 当一个路由下面的 children 声明的路由大于1个时，自动会变成嵌套的模式
        //? 只有一个时，会将那个子路由当做根路由显示在侧边栏
        //? 若想不管路由下面的 children 声明的个数都显示你的根路由
        //? 可以设置 alwaysShow: true，这样就会忽略之前定义的规则，一直显示根路由
        alwaysShow: true
        //? 示例: activeMenu: "/xxx/xxx"
        //? 当设置了该属性进入路由时，则会高亮 activeMenu 属性对应的侧边栏
        //? 该属性适合使用在有 hidden: true 属性的路由上
        activeMenu: '/dashboard'
        //? 是否缓存该路由页面
        //? 默认为 false，为 true 时代表需要缓存，此时该路由和该页面都需要设置一致的 Name
        keepAlive: false
      }
    },
  */
	// #endregion
	{
		path: '/redirect',
		component: Layouts,
		meta: {
			hidden: true,
		},
		children: [
			{
				path: ':path(.*)',
				component: () => import('@/views/redirect/index.vue'),
			},
		],
	},
	{
		path: '/403',
		component: () => import('@/views/error-page/403.vue'),
		meta: {
			hidden: true,
		},
	},
	{
		path: '/404',
		component: () => import('@/views/error-page/404.vue'),
		meta: {
			hidden: true,
		},
		alias: '/:pathMatch(.*)*',
	},
	{
		path: '/login',
		component: () => import('@/views/login/index.vue'),
		meta: {
			hidden: true,
		},
	},
	{
		path: '/',
		component: Layouts,
		redirect: '/dashboard',
		children: [
			{
				path: 'dashboard',
				component: () => import('@/views/dashboard/index.vue'),
				name: 'Dashboard',
				meta: {
					title: '首页',
					svgIcon: 'dashboard',
					affix: true,
				},
			},
		],
	},
	{
		path: '/vueUse',
		component: Layouts,
		redirect: '/vueUse/index',
		children: [
			{
				path: 'index',
				component: () => import('@/views/vueUse/index.vue'),
				name: 'vueUse',
				meta: {
					title: 'vueUse',
					elIcon: 'ChromeFilled',
				},
			},
		],
	},
	{
		path: '/unocss',
		component: Layouts,
		redirect: '/unocss/index',
		children: [
			{
				path: 'index',
				component: () => import('@/views/unocss/index.vue'),
				name: 'UnoCSS',
				meta: {
					title: 'UnoCSS',
					svgIcon: 'unocss',
				},
			},
		],
	},
	{
		path: '/wangeditor',
		component: Layouts,
		redirect: '/wangeditor/index',
		children: [
			{
				path: 'index',
				component: () => import('@/views/wangeditor/index.vue'),
				name: 'wangeditor',
				meta: {
					title: 'wangeditor',
					elIcon: 'ChromeFilled',
				},
			},
		],
	},
	{
		path: '/office',
		component: Layouts,
		redirect: '/office/index',
		children: [
			{
				path: 'index',
				component: () => import('@/views/office/index.vue'),
				name: 'office',
				meta: {
					title: 'office',
					elIcon: 'ChromeFilled',
				},
			},
		],
	},
	{
		path: '/link',
		meta: {
			title: '外链',
			svgIcon: 'link',
		},
		children: [
			{
				path: 'https://juejin.cn/post/7089377403717287972',
				component: () => {},
				name: 'Link1',
				meta: {
					title: '中文文档',
				},
			},
			{
				path: 'https://juejin.cn/column/7207659644487139387',
				component: () => {},
				name: 'Link2',
				meta: {
					title: '新手教程',
				},
			},
		],
	},
	{
		path: '/table',
		component: Layouts,
		redirect: '/table/element-plus',
		name: 'Table',
		meta: {
			title: '表格',
			elIcon: 'Grid',
		},
		children: [
			{
				path: 'element-plus',
				component: () => import('@/views/table/element-plus/index.vue'),
				name: 'ElementPlus',
				meta: {
					title: 'Element Plus',
					keepAlive: true,
				},
			},
			{
				path: 'vxe-table',
				component: () => import('@/views/table/vxe-table/index.vue'),
				name: 'VxeTable',
				meta: {
					title: 'Vxe Table',
					keepAlive: true,
				},
			},
		],
	},
	{
		path: '/menu',
		component: Layouts,
		redirect: '/menu/menu1',
		name: 'Menu',
		meta: {
			title: '多级路由',
			svgIcon: 'menu',
		},
		children: [
			{
				path: 'menu1',
				component: () => import('@/views/menu/menu1/index.vue'),
				redirect: '/menu/menu1/menu1-1',
				name: 'Menu1',
				meta: {
					title: 'menu1',
				},
				children: [
					{
						path: 'menu1-1',
						component: () => import('@/views/menu/menu1/menu1-1/index.vue'),
						name: 'Menu1-1',
						meta: {
							title: 'menu1-1',
							keepAlive: true,
						},
					},
					{
						path: 'menu1-2',
						component: () => import('@/views/menu/menu1/menu1-2/index.vue'),
						redirect: '/menu/menu1/menu1-2/menu1-2-1',
						name: 'Menu1-2',
						meta: {
							title: 'menu1-2',
						},
						children: [
							{
								path: 'menu1-2-1',
								component: () => import('@/views/menu/menu1/menu1-2/menu1-2-1/index.vue'),
								name: 'Menu1-2-1',
								meta: {
									title: 'menu1-2-1',
									keepAlive: true,
								},
							},
							{
								path: 'menu1-2-2',
								component: () => import('@/views/menu/menu1/menu1-2/menu1-2-2/index.vue'),
								name: 'Menu1-2-2',
								meta: {
									title: 'menu1-2-2',
									keepAlive: true,
								},
							},
						],
					},
					{
						path: 'menu1-3',
						component: () => import('@/views/menu/menu1/menu1-3/index.vue'),
						name: 'Menu1-3',
						meta: {
							title: 'menu1-3',
							keepAlive: true,
						},
					},
				],
			},
			{
				path: 'menu2',
				component: () => import('@/views/menu/menu2/index.vue'),
				name: 'Menu2',
				meta: {
					title: 'menu2',
					keepAlive: true,
				},
			},
		],
	},
	{
		path: '/hook-demo',
		component: Layouts,
		redirect: '/hook-demo/use-fetch-select',
		name: 'HookDemo',
		meta: {
			title: 'Hook',
			elIcon: 'Menu',
			alwaysShow: true,
		},
		children: [
			{
				path: 'use-fetch-select',
				component: () => import('@/views/hook-demo/use-fetch-select.vue'),
				name: 'UseFetchSelect',
				meta: {
					title: 'useFetchSelect',
				},
			},
			{
				path: 'use-fullscreen-loading',
				component: () => import('@/views/hook-demo/use-fullscreen-loading.vue'),
				name: 'UseFullscreenLoading',
				meta: {
					title: 'useFullscreenLoading',
				},
			},
			{
				path: 'use-watermark',
				component: () => import('@/views/hook-demo/use-watermark.vue'),
				name: 'UseWatermark',
				meta: {
					title: 'useWatermark',
				},
			},
		],
	},
];

/**
 * 动态路由
 * 用来放置有权限 (Roles 属性) 的路由
 * 必须带有 Name 属性
 */
export const dynamicRoutes: RouteRecordRaw[] = [
	{
		path: '/permission',
		component: Layouts,
		redirect: '/permission/page',
		name: 'Permission',
		meta: {
			title: '权限',
			svgIcon: 'lock',
			roles: ['admin', 'editor'], // 可以在根路由中设置角色
			alwaysShow: true, // 将始终显示根菜单
		},
		children: [
			{
				path: 'page',
				component: () => import('@/views/permission/page.vue'),
				name: 'PagePermission',
				meta: {
					title: '页面级',
					roles: ['admin'], // 或者在子导航中设置角色
				},
			},
			{
				path: 'directive',
				component: () => import('@/views/permission/directive.vue'),
				name: 'DirectivePermission',
				meta: {
					title: '按钮级', // 如果未设置角色，则表示：该页面不需要权限，但会继承根路由的角色
				},
			},
		],
	},
];

const router = createRouter({
	history,
	routes: routeSettings.thirdLevelRouteCache ? flatMultiLevelRoutes(constantRoutes) : constantRoutes,
});

/** 重置路由 */
export function resetRouter() {
	// 注意：所有动态路由路由必须带有 Name 属性，否则可能会不能完全重置干净
	try {
		router.getRoutes().forEach((route) => {
			const { name, meta } = route;
			if (name && meta.roles?.length) {
				router.hasRoute(name) && router.removeRoute(name);
			}
		});
	} catch {
		// 强制刷新浏览器也行，只是交互体验不是很好
		window.location.reload();
	}
}

export default router;
